Die Ergebnisse arithmetischer und logischer Operationen beeinflussen den Zustand der Flags, das sind spezielle Statusbits im Prozessor. Flags geben an, ob zum Beispiel das Ergebnis einer Berechnung Null war, ob ein Überlauf aufgetreten ist oder ob das Ergebnis negativ ist. Diese Flags sind entscheidend für die Kontrolle des Programmflusses, da sie die Grundlage für bedingte Sprünge und Entscheidungen im Programmablauf bilden. Somit sorgt die ALU durch ihre Operationen und die Nutzung von Flags für die korrekte Verarbeitung und Steuerung von Programmen.
Das Current Program Status Register (CPSR) in der ARMv7-Architektur ist ein spezielles Register, das wichtige Informationen über den Zustand des Prozessors speichert und steuert.
Das CPSR-Register ist 32 Bit breit und in verschiedene Felder unterteilt, die jeweils unterschiedliche Informationen enthalten: Condition Flags (N, Z, C, V): Diese Flags befinden sich in den oberen 4 Bits (Bits 31 bis 28) des Registers. Sie werden von arithmetischen und logischen Operationen beeinflusst und helfen dabei, den Zustand des Ergebnisses einer Berechnung zu bestimmen.
31 | 30 | 29 | 28 | … |
---|---|---|---|---|
N | Z | C | V | … |
Das CPSR kann durch Anweisungen beeinflusst werden, die eine Berechnung durchführen und dabei die Condition Flags setzen. Dies wird erreicht, indem ein s
am Ende der Operation angehängt wird. Diese erweiterte Syntax sorgt dafür, dass die entsprechenden Flags im CPSR basierend auf dem Ergebnis der Operation aktualisiert werden.
MOVS <Zielregister>, <Quelle>
ADDS <Zielregister>, <Quellregister>, <Quelle>
SUBS <Zielregister>, <Quellregister>, <Quelle>
MULS <Zielregister>, <Quellregister1>, <Quellregister2>
Nehmen wir an, dass zwei Register denselben Wert enthalten und diese Werte voneinander subtrahiert werden. In diesem Fall sollte das Ergebnis 0 sein, wodurch das Zero-Flag (Z) im CPSR-Register gesetzt wird.
MOV R0, #7 @ Lade den Wert 7 in Register R0
MOV R1, #7 @ Lade den Wert 7 in Register R1
SUBS R2, R0, R1 @ Subtrahiere R1 von R0, speichere das Ergebnis in R2 und setze die Flags
Nach der Operation SUBS zeigt das gesetzte Zero-Flag (Z) im CPSR an, dass das Ergebnis der Subtraktion Null war. Das Zero-Flag befindet sich im CPSR an Bit 30. Wenn das Ergebnis der Operation Null ist, wird dieses Bit auf 1 gesetzt. Betrachtet man das Ergebnis im CPU-Lator, so wird ersichtlich, dass auch das Carry-Flag (C) gesetzt wurde:
Register R0, R1, R2 nach Ausführung
CPSR nach Ausführung
Wenn man die oberen vier Bits (Bits 31 bis 28) des CPSR, die die Condition-Flags repräsentieren, nach dieser Operation binär darstellt, ergibt sich die Folge 0110 (in hexadezimal 0x6, wie auch in CPULator angezeigt). Dies bedeutet, dass das Zero-Flag (Bit 30) und das Carry-Flag (Bit 29) gesetzt sind.
Bei Subtraktionen zeigt die Carry-Flag an, dass kein Borrow (Untertrag) notwendig war. Ein Borrow tritt auf, wenn der Minuend (die Zahl, von der subtrahiert wird) kleiner ist als der Subtrahend (die abzuziehende Zahl).
Achtung: In der ARM-Architektur wird die Carry-Flag als negierte Borrow-Flag verwendet:
Bei der Subtraktion 7-7 wird das Ergebnis 0 weshalb das Zero-Bit gesetzt wird. Dadurch, dass kein Unterlauf auftretet, wird das Carry-Bit auch auf 1 gesetzt. Bei der Subtraktion 7-10 wäre das Carry-Bit auf 0 gesetzt (aber auch das Zero-Bit, da das Ergebnis nicht 0 ist), da durch das abziehen einer größeren Zahl ein Untertrag entsteht.
Wie im vorherigen Beispiel gezeigt wurde, wird das Carry-Bit bei einer Subtraktion ohne Untertrag gesetzt. Bei der Addition ist es jedoch umgekehrt: Wenn es bei einer Addition zu einem Übertrag kommt, wird das Carry-Flag auf 1 gesetzt.. In diesem Beispiel addieren wir 2 zu 0xFFFFFFFF, dem größten Wert, der im 32-Bit-Register dargestellt werden kann. Dies führt zu einem Überlauf:
MOV R0, #0xFFFFFFFF @ Register R0 wird mit 0xFFFFFFFF (alle 1er) geladen
MOV R1, #0x2 @ Lade den Wert 2 in Register R1
ADDS R2, R0, R1 @ Addiere R1 auf R0, speichere das Ergebnis in R2 und setze die Flags
So sieht das Ergebnis dann in CPULator aus:
Register R0, R1, R2 nach Ausführung
So sieht die Unvorzeichenbehaftete Addition aus:
11111111 11111111 11111111 11111111 (0xFFFFFFFF in Binär)
+ 00000000 00000000 00000000 00000010 (0x2 in Binär)
--------------------------------------
(1) 00000000 00000000 00000000 00000001 (Ergebnis: 0x00000001)
Die Addition von 0xFFFFFFFF und 2 ergibt 0x00000001. Dies liegt daran, dass die größte Zahl in einem 32-Bit-System (0xFFFFFFFF) bei der Addition von 2 einen Überlauf (Carry) verursacht, der den Wert zurück auf 1 bringt. Die 1, die sich im 32ten Bit ergeben würde, wird abgeschnitten, da das Resgistern nur eine Größe von 32 Bits hat (0-31tes Bit werden dargestellt).
So sieht das CPSR nach der Ausführung aus:
Wenn man die oberen vier Bits (Bits 31 bis 28) des CPSR, die die Condition-Flags repräsentieren, nach dieser Operation binär darstellt, ergibt sich die Folge 0010 (in hexadezimal 0x2, wie auch in CPULator angezeigt). Dies bedeutet, dass das Carry-Flag (Bit 29) wie erwartet gesetzt wurde.
zurück | Hauptmenü | weiter |